package com.example.fill;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MyView extends View {

    private Bitmap mSrcBitmap, mDstBitmap, bBitmap,lineBitmap,mixBitmap,pathBitmap;
    private Canvas mSrcCanvas, mDstCanvas, mCanvas,lineCanvas,mixCanvas,pathCanvas;
    private Paint paint, paintBG, shadowPaint, paintCircle;
    private Paint mSrcPaint;
    private Paint yPaint = new Paint();
    private Path path = new Path();
    private Bitmap mBitmapAll;
    private Canvas mCanvasAll;
    private List<Point> points = new ArrayList<>();

    public MyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init(){
        yPaint.setAntiAlias(true);
        yPaint.setColor(Color.BLACK);
        yPaint.setStyle(Paint.Style.STROKE);
        yPaint.setStrokeWidth(4f);

        paint = new Paint();
        paint.setAntiAlias(true);               // 抗锯齿
        paint.setColor(Color.BLACK);             // 画笔颜色 - 黑色
        paint.setStyle(Paint.Style.STROKE);     // 填充模式 - 描边
        paint.setStrokeWidth(4f);
        paint.setStrokeJoin(Paint.Join.ROUND);
        mSrcPaint = new Paint();
        mSrcPaint.setAntiAlias(true);
        mSrcPaint.setStrokeWidth(4f);
        mSrcPaint.setStrokeJoin(Paint.Join.ROUND);
        paintCircle = new Paint();
        paintCircle.setAntiAlias(true);               // 抗锯齿
        paintCircle.setColor(Color.BLACK);             // 画笔颜色 - 黑色
        paintCircle.setStyle(Paint.Style.FILL);     // 填充模式 - 描边
        paintCircle.setStrokeJoin(Paint.Join.ROUND);
        paintBG = new Paint();
        paintBG.setAntiAlias(true);
        shadowPaint = new Paint();
        shadowPaint.setAntiAlias(true);//抗锯齿
        shadowPaint.setColor(Color.BLUE);
        points.addAll(Arrays.asList(
                new Point(100,-100),
                new Point(200,-250),
                new Point(300,-370),
                new Point(400,-220),
                new Point(500,-330),
                new Point(600,-460),
                new Point(700,-800),
                new Point(800,-120),
                new Point(900,-200),
                new Point(1000,0)
        ));
        for (Point point : points) {
            path.lineTo(point.x,point.y);
        }
    }

    private void initSrc() {
        if (mSrcBitmap == null) {
            mSrcBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
            mSrcCanvas = new Canvas(mSrcBitmap);
        }
        if (mDstBitmap == null) {
            mDstBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
            mDstCanvas = new Canvas(mDstBitmap);
        }
        if (bBitmap == null) {
            bBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
            mCanvas = new Canvas(bBitmap);
        }
        if (mBitmapAll == null) {
            mBitmapAll = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
            mCanvasAll = new Canvas(mBitmapAll);
        }
        if (lineBitmap == null){
            lineBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
            lineCanvas = new Canvas(lineBitmap);
        }
        if (mixBitmap == null){
            mixBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
            mixCanvas = new Canvas(mixBitmap);
        }
        if (pathBitmap == null){
            pathBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
            pathCanvas = new Canvas(pathBitmap);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int[] colors = {Color.BLACK, Color.BLUE,Color.RED};
        float[] positions = {0, 0.5f, 1};
        LinearGradient linearGradient = new LinearGradient(0, 0, 0, getMeasuredHeight(), colors, positions, Shader.TileMode.CLAMP);
        paintBG.setShader(linearGradient);
        initSrc();

    }

    @Override
    protected void onDraw(Canvas canvas) {
        //path
        mDstCanvas.translate(0,getHeight()/2);
        mDstCanvas.drawPath(path,mSrcPaint);
        //BG
        mSrcCanvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paintBG);
        //path
        pathCanvas.translate(0,getHeight()/2);
        pathCanvas.drawPath(path,yPaint);
        mixCanvas.drawBitmap(pathBitmap,0,0,null);
        //line
        lineCanvas.drawLine(touchPoint.x,0,touchPoint.x,getMeasuredHeight(),yPaint);
        //mix
        yPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));
        mixCanvas.drawBitmap(lineBitmap,0,0,yPaint);
        yPaint.setXfermode(null);
        //all
        mCanvas.drawBitmap(mDstBitmap,0,0,shadowPaint);
        mSrcPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        mCanvas.drawBitmap(mSrcBitmap,0,0,mSrcPaint);
        mSrcPaint.setXfermode(null);
        mCanvas.drawBitmap(mixBitmap,0,0,null);

        canvas.drawBitmap(bBitmap,0,0,null);
    }

    private PointF touchPoint = new PointF(500,500);
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                touchPoint.x = event.getX();
                touchPoint.y = event.getY();
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                touchPoint.x = event.getX();
                touchPoint.y = event.getY();
                invalidate();
                break;
            case MotionEvent.ACTION_UP:

                break;
        }

        return true;
    }
}
